
package com.ng.sys.service.impl;


import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ng.common.cache.annotation.TrCache;
import com.ng.common.cache.annotation.TrCacheEvict;
import com.ng.common.cache.annotation.TrCacheEvict.EvictType;
import com.ng.common.service.CacheServiceImpl;
import com.ng.common.utils.Constant;
import com.ng.sys.dao.SysMenuDao;
import com.ng.sys.entity.SysMenuEntity;
import com.ng.sys.entity.SysRoleMenuEntity;
import com.ng.sys.service.SysMenuService;
import com.ng.sys.service.SysRoleMenuService;


@Service 
public class SysMenuServiceImpl extends CacheServiceImpl<SysMenuDao, SysMenuEntity> implements SysMenuService {
 
	@Autowired
	private SysRoleMenuService sysRoleMenuService;
  
	 
	public List<SysMenuEntity> queryListParentId(String parentId, List<String> menuIdList , List<SysMenuEntity> allMenu) {
		List<SysMenuEntity> menuList = allMenu.stream().
					filter(t-> (menuIdList != null ? menuIdList.contains(t.getMenuId()) : true ) && (t.getParentId() != null ? t.getParentId().equals(parentId) : true ))
					.sorted((t1 , t2)-> t1.getOrderNum().compareTo(t2.getOrderNum()))
					.collect(Collectors.toList());
	 
		return menuList;
	}
 
	@Override
	@TrCache("'queryNotButtonList'")
	public List<SysMenuEntity> queryNotButtonList() {
		 
		List<SysMenuEntity> list = baseMapper.queryNotButtonList();
		 
		
		return list ;
	}

 
	 
	@TrCache("'getAllMenu'")
	public List<SysMenuEntity> getAllMenu() {
		 

		QueryWrapper<SysMenuEntity> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("enabled",1);
		List<SysMenuEntity> list = super.list(queryWrapper);
		 
		
		return list ;
	}
	
	@Override
	@TrCacheEvict(value="#className" , type=EvictType.start)
	public void delete(String menuId){
		//删除菜单
		this.removeById(menuId);
		//删除菜单与角色关联
		UpdateWrapper<SysRoleMenuEntity> wrapper = new UpdateWrapper<>();
		wrapper.eq("menu_id", menuId);
		
		sysRoleMenuService.remove(wrapper);
		 
		clearCache();
	}
	


	/**
	 * 获取所有菜单列表
	 */
	private List<SysMenuEntity> getAllMenuList(List<String> menuIdList , String userId){
		
		// 拿到所有菜单
		List<SysMenuEntity> allMenu = getAllMenu();
		if(allMenu == null || allMenu.isEmpty()) return Collections.emptyList() ;

		//SysUser user = securityUtils.getCurrentUser();
		List<String> pid = this.baseMapper.queryParentByUser(userId);
		if (!pid.isEmpty()&&null != menuIdList){
			menuIdList.removeAll(pid);
			menuIdList.addAll(pid);
		}
		//查询根菜单列表
		List<SysMenuEntity> menuList = queryListParentId("0", menuIdList ,allMenu);
 
		//递归获取子菜单
		getMenuTreeList(menuList, menuIdList ,allMenu);
		
		return menuList;
	}

	/**
	 * 递归
	 */
	private List<SysMenuEntity> getMenuTreeList(List<SysMenuEntity> menuList, List<String> menuIdList , List<SysMenuEntity> allMenu){
		List<SysMenuEntity> subMenuList = new ArrayList<SysMenuEntity>();
		
		for(SysMenuEntity entity : menuList){
			//目录
			//if(entity.getType().getValue() <= MenuType.CATALOG.getValue()){
				entity.setList(getMenuTreeList(queryListParentId(entity.getMenuId(), menuIdList,allMenu), menuIdList ,allMenu));
			//}
			subMenuList.add(entity);
		}
		
		return subMenuList;
	}
	
	@Override
	public List<SysMenuEntity> queryListParentId(String parentId) {
		 
		return baseMapper.queryListParentId(parentId);
	}
 

	@Override 
	@TrCache(value= "'" + CACHE_USER_MENU + "' + #userId" )
	public List<SysMenuEntity> getUserMenuList(String userId) {
 
		List<SysMenuEntity> list = new ArrayList<>();
		//系统管理员，拥有最高权限
		if(userId.equals(Constant.SUPER_ADMIN) ){
			list = getAllMenuList(null , userId);
		} else {
			//用户菜单列表
			List<String> menuIdList = baseMapper.queryAllMenuId(userId);
			list = getAllMenuList(menuIdList , userId);
		}
		  
		
		return list ;
	}

   
	@Override
	@TrCache(value="'" + CACHE_USER_PERM + "' + #userId" )
	public Set<String> queryAllPerms(String userId) {
 
		 
		Set<String> perms = new HashSet<>();
		
		if(userId.equals(Constant.SUPER_ADMIN)) {
			List<SysMenuEntity> all = getAllMenu();
			 
			all.forEach(t->{
				if(StringUtils.isBlank(t.getPerms())) return ;
				String[] ss = t.getPerms().split(",");
				
				for(String s : ss)
					perms.add(s);
				
			});
		} else {
			Set<String> list = baseMapper.queryAllPerms(userId);
			list.forEach(t->{
				if(StringUtils.isBlank(t)) return ;
				String[] ss = t.split(",");
				
				for(String s : ss)
					perms.add(s);
			});	
		} 
		 

		return perms ;  
	}
	
	public void clearUserPerms(String userId) {
		
		String key = getRedisKey(CACHE_USER_MENU + userId);
		
		redisUtils.delete(key);
		
		key = getRedisKey(CACHE_USER_PERM + userId);
		
		redisUtils.delete(key);
		
		
	}

	@Override
	public boolean removeByIds(Collection<? extends Serializable> idList) {
		// TODO Auto-generated method stub
		clearCache();
		return super.removeByIds(idList);
	}
	
	@Override
	public boolean removeById(Serializable id) {
		// TODO Auto-generated method stub
		clearCache();
		return super.removeById(id);
	}
	
	@Override
	public boolean updateById(SysMenuEntity entity) {
		// TODO Auto-generated method stub
		clearCache();
		return super.updateById(entity);
	}
	
	@Override
	public boolean save(SysMenuEntity entity) {
		// TODO Auto-generated method stub
		clearCache();
		return super.save(entity);
	}
	
}
